package com.penghk.earth.util;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

public class RSAUtil {

    /**
     * 加密算法RSA
     */
    public static final String  KEY_ALGORITHM = "RSA";

    /**
     * 密钥长度1024
     */
    public static final int KEY_SIZE = 1024;

    /**
     * 获取公钥的key
     */
    private static final String PUBLIC_KEY          = "RSAPublicKey";

    /**
     * 获取私钥的key
     */
    private static final String PRIVATE_KEY         = "RSAPrivateKey";


    public static void main(String[] args) throws Exception {

//        byte[] arr = new byte[3];
//        arr[0] = -125;
//        arr[1] = 16;
//        arr[2] = 0;
//        BASE64Encoder encoder = new BASE64Encoder();
//        String enStr = encoder.encode(arr);
//        System.out.println(enStr);
//
//        String url = "amount=1&amt_type=RMB&card_holder=VfZQiTruzDaXCPH8wxqWJ0ccpWI912HHpSYwvUmZ2%2FrgZDESijKHplGTd7mgXrQsolAJn%2FPYTr5bP16T2WBxrbNpCfb9ObkTEa%2FWnVnnIFl%2BeHBOsdL8BGhpLucrO4bu0z4tM%2BegIAxx36M%2BQ7%2BzrPTQGwFKVD97y1pbU1w7tns%3D&card_id=WOymaScdAFsDQ7AXalyZMvSdToRkctul4EfISJJbJYrth%2BLkjAy%2FkEhmq5rJVs8GhwmNlf28rbF4WcBmGKEfV%2FneZtg4RWBZ097TObsruEFlcsdGrT7Kjmpd6ubqcmzGRAanPkjZp2L3iv%2FWC1OCxQKuJ7VECfdn3isAQ3V0EeU%3D&charset=UTF-8&debit_pay_type=1&identity_code=KJyHGhGMTLsHozIlXDkL%2BLJJk2Yh0FlkQ5yXB94tpO9a0jkoQMKN368RjTtsnGe9pp2a4ApoQ1rCuxhOG2TlQlhqVlMFDdY8i84U9%2BaQf1cviyI0dccExJtkStSS5SmZ5t%2BYNirnN793f%2B5J%2BiwWRw5Z67IqglDLxrmobIqAAjk%3D&identity_type=IDENTITY_CARD&mer_date=20171201&mer_id=6374&notify_url=http%3A%2F%2F114.113.159.207%3A8756%2Fpgtest%2Fnotify0000V4.jsp&order_id=546799&pass_wd=&pay_type=DEBITCARD&service=debit_direct_pay&sign_type=RSA&version=4.0";
//        String filePath = "/home/penghk/文档/联动证书/pkcs8.pem";
//        PrivateKey privateKey = getPem(filePath);
//        String signStr = sign(url,privateKey,"utf-8");
//        url += "&sign="+signStr;
//        System.out.println(url);


        Map<String ,Key> keyMap = genKeyPair();
        String priKey = getPrivateKey(keyMap);
        String pubKey = getPublicKey(keyMap);
        System.out.println("pri : \n"+priKey);
        System.out.println("pub : \n"+pubKey);

        String passwd = "123qwe";
        String encryptPasswd = encryptByPublicKey(passwd , pubKey);
        System.out.println("encryptPasswd ； "+encryptPasswd);
    }

    private static String encryptByPublicKey(String passwd, String pubKey) {
        return "";
    }

    public static Map<String ,Key> genKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        generator.initialize(KEY_SIZE);
        KeyPair keyPair = generator.generateKeyPair();
        Key priKey = keyPair.getPrivate();
        Key pubKey = keyPair.getPublic();
        Map<String, Key> keyMap = new HashMap<String, Key>(2);
        keyMap.put(PUBLIC_KEY, pubKey);
        keyMap.put(PRIVATE_KEY, priKey);
        return keyMap;
    }

    /**
     * <p>
     * 获取公钥
     * </p>
     *
     * @param keyMap 密钥对
     * @return
     * @throws Exception
     */
    public static String getPublicKey(Map<String, Key> keyMap) throws Exception {
        Key key = (Key) keyMap.get(PUBLIC_KEY);
        BASE64Encoder encoder = new BASE64Encoder();
        String pubKey = encoder.encode(key.getEncoded());
        return pubKey;
    }

    /**
     * <p>
     * 获取公钥
     * </p>
     *
     * @param keyMap 密钥对
     * @return
     * @throws Exception
     */
    public static String getPrivateKey(Map<String, Key> keyMap) throws Exception {
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        BASE64Encoder encoder = new BASE64Encoder();
        String priKey = encoder.encode(key.getEncoded());
        return priKey;
    }


    /**
     * 从文件获取私钥
     * @param fileName
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static PrivateKey getPem(String fileName) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
        BufferedReader reader = new BufferedReader(new FileReader(fileName));
        String s = reader.readLine();
        StringBuilder stringBuffer = new StringBuilder();
        s = reader.readLine();
        while (s.charAt(0)!= '-') {
            stringBuffer.append(s);
            stringBuffer.append("\r");
            s = reader.readLine();
        }
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] deRes = decoder.decodeBuffer(stringBuffer.toString());
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(deRes);
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
//        System.out.println("私钥 ： "+new String(privateKey.getEncoded()));
        return privateKey;
    }

    /**
     * 签名算法
     */
    public static final String  SIGNATURE_ALGORITHM = "SHA1withRSA";

    /**
     * 签名字符串
     *
     * @param text
     *            需要签名的字符串
     * @param privateKey 私钥(BASE64编码)
     * @param charset
     *
     *            编码格式
     * @return 签名结果(BASE64编码)
     */
    public static String sign(String text, PrivateKey privateKey, String charset) throws Exception {

        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(privateKey);
        signature.update(getContentBytes(text, charset));
        byte[] result = signature.sign();
        BASE64Encoder encoder = new BASE64Encoder();
        String sign = encoder.encode(result);
        System.out.println(sign);
        return sign;

    }

    {
//        getClass().getResourceAsStream("");
    }
    /**
     * @param content
     * @param charset
     * @return
     * @throws SignatureException
     * @throws UnsupportedEncodingException
     */
    private static byte[] getContentBytes(String content, String charset) {
        if (charset == null || "".equals(charset)) {
            return content.getBytes();
        }
        try {
            return content.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
        }
    }

}
